package Tests.model;

import model.Card;
import model.CardPileRecycle;
import model.Face;
import model.Suit;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class CardPileRecycleTest {
    private CardPileRecycle recycle;
    private List<Card> fourCardsSameRank; 

    @Before
    public void setUp() {
        recycle = new CardPileRecycle();
        fourCardsSameRank = new ArrayList<Card>();

        // populate four cards with the same rank
        for (Suit suit : Suit.values()) {
            Card card = new Card(Face.FIVE, suit);
            fourCardsSameRank.add(card);
        }
    }
    
    @Test
    public void getFaces_EmptyRecycle_ZeroFaces() {
        List<Face> faces = recycle.getFaces();
        
        Assert.assertEquals(0, faces.size());
    }

    // refactor this test using decorators
    @Test
    public void getFaces_12Cards_3Faces() {
        // create aces
        List<Card> aces = new ArrayList<Card>();
        List<Card> kings = new ArrayList<Card>();
        List<Card> tens = new ArrayList<Card>();

        for (Suit suit : Suit.values()) {
            Card ace = new Card(Face.ACE, suit);
            aces.add(ace);
            
            Card king = new Card(Face.KING, suit);
            kings.add(king);
            
            Card ten = new Card(Face.TEN, suit);
            tens.add(ten);
        }
        recycle.push(aces);
        recycle.push(kings);
        recycle.push(tens);
        
        List<Face> faces = recycle.getFaces();
        
        Assert.assertEquals(3, faces.size());
        Assert.assertEquals(Face.ACE, faces.get(0));
        Assert.assertEquals(Face.KING, faces.get(1));
        Assert.assertEquals(Face.TEN, faces.get(2));
    }

    
    @Test(expected = IllegalArgumentException.class)
    public void push_5Cards_ThrowArgumentException() {
        Card card = new Card(Face.ACE, Suit.DIAMONDS);
        fourCardsSameRank.add(card);
        recycle.push(fourCardsSameRank);
    }
    
    @Test(expected = NullPointerException.class)
    public void push_NullListPointer_ThrowNullPointerException() {
        List<Card> cards;
        cards = null;
        recycle.push(cards);
    }
    
    @Test
    public void push_fourCardsSameRank_AddCards() {
        int initialCount = recycle.size();
        recycle.push(fourCardsSameRank);
        Assert.assertEquals(initialCount + 4, recycle.size());
    }
    
    @Test
    public void push_fourCardsSameRank_addFace() {
        int initialCount = recycle.getFaces().size();
        recycle.push(fourCardsSameRank);
        Assert.assertEquals(initialCount + 1, recycle.getFaces().size());
    }
    
    @Test
    public void contains_ExistedRank_ReturnTrue() {
        List<Card> aces = new ArrayList<Card>();

        // populate
        for (Suit suit : Suit.values()) {
            Card card = new Card(Face.ACE, suit);
            aces.add(card);
        }

        recycle.push(aces);
        
        Assert.assertTrue(recycle.contains(Face.ACE));
    }
    
    @Test
    public void contains_NotExistedRank_ReturnFalse() {
        List<Card> aces = new ArrayList<Card>();
        
        for (Suit suit : Suit.values()) {
            Card ace = new Card(Face.ACE, suit);
            aces.add(ace);
        }

        recycle.push(aces);
        
        Assert.assertFalse(recycle.contains(Face.JACK));
    }
}
